#include "type.h"
#include "hluart.h"
#include <stdio.h>
u8 type_get_size(u8 type);
void get_buffer_from_data(u32 data, u8 size, u8 *buffer);
u32 __get_data_from_buffer(const u8 *buffer_p, u8 size);
// // 根据协议的元素数量
// u16 elements_size()
// {
//     u8 agreement[] = AGREEMENT;
//     return sizeof(agreement) / sizeof(u8);
// }
// // 元素组初始化，根据协议返回buffer字节数量
// u16 elements_init(Element elements[])
// {
//     u8 agreement[] = AGREEMENT;
//     u16 agreement_length = sizeof(agreement) / sizeof(u8);
//     u16 buffer_size = 0;
//     for (u16 i = 0; i < agreement_length; i++)
//     {
//         elements[i].type = agreement[i];
//         elements[i].size = type_get_size(agreement[i]);
//         buffer_size += elements[i].size;
//     }
//     return buffer_size;
// }

u16 get_elements_length(u8 *buffer, u16 size)
{
		int i;
    u16 length = 0;
    for (i = 0; i < size;)
    {
        i += (type_get_size(buffer[i]) + 1);
        length++;
    }
    return length;
}
// 读取buffer,补充元素组的data(不包含校验，buffer应在外部校验完成才可调用！！！)
void read_buffer(u8 *buffer, u16 length, Element elements[])
{
		u32 temp;
		int i;
    u8 *ptr = buffer;
    // u16 length = get_elements_length(buffer, size);
    // printf("%d\n", length);
    for (i = 0; i < length; i++)
    {
        elements[i].type = *ptr;
        ptr += 1;
        elements[i].size = type_get_size(elements[i].type);
        temp = __get_data_from_buffer(ptr, elements[i].size);

        elements[i].data = temp;
        // printf("%x,%d\n", elements[i].data, elements[i].size);
        ptr += elements[i].size;
    }
}
// 写buffer
void write_buffer(u8 *buffer, u16 length, Element elements[])
{
		int i;
    u8 *ptr = buffer;
    for (i = 0; i < length; i++)
    {
        *ptr = elements[i].type;
        ptr += 1;
        get_buffer_from_data(elements[i].data, elements[i].size, ptr);
        // elements[i].data=__get_data_from_buffer(ptr,elements[i].size);
        ptr += elements[i].size;
    }
}
u8 type_get_size(u8 type)
{
    u8 res = 0;
    switch (type)
    {
    case T_UINT8:
        res = 1;
        break;
    case T_INT16:
    case T_UINT16:
        res = 2;
        break;
    case T_UINT32:
    case T_INT32:
    case T_FLOAT:
        res = 4;
        break;
    }
    return res;
}

u32 __get_data_from_buffer(const u8 *buffer_p, u8 size)
{
    u32 res;
    u32 temp = 0;
    u8 t1;
    u16 t2;
    switch (size)
    {
    case 1:
        t1 = *(u8 *)buffer_p;
        temp = (u32)t1;
        res = temp;
        break;
    case 2:
        // res=*(u16 *)buffer_p;break;
        t2 = *(u16 *)buffer_p;
        res = *(u32 *)(&t2);
        // res=(u16 *)buffer_p;
        break;
    case 4:
        res = *(u32 *)buffer_p;
        break;
    }
    return res;
}
#define DATA_TO_BUFFER 1
#define BUFFER_TO_DATA 2
void main_function(u32 *data, u8 *buffer, u8 size, u8 mode)
{
		int i;
    if (mode == BUFFER_TO_DATA)
    {
        *data = __get_data_from_buffer(buffer, size);
    }
    else if (mode == DATA_TO_BUFFER)
    {
        u8 *ptr = (u8 *)(data);
        for (i = 0; i < size; i++)
        {
            buffer[i] = ptr[i];
        }
    }
}
// 通过data获得buffer
void get_buffer_from_data(u32 data, u8 size, u8 *buffer)
{
    main_function(&data, buffer, size, DATA_TO_BUFFER);
}
// 通过buffer获得data
void get_data_from_buffer(u32 *data, u8 size, u8 *buffer)
{
    main_function(data, buffer, size, BUFFER_TO_DATA);
}
// 通过val获得data
#define get_data_from_val(val) (__get_data_from_buffer((u8 *)(&(val)), sizeof(val)))
u32 data(void *val, u8 type)
{
    return __get_data_from_buffer((u8 *)(val), type_get_size(type));
}

void val(void *val, u8 type, u32 data)
{
    if (type == T_FLOAT)
    {
        f32 *p = val;
        *p = def_val(data, f32);
    }
    else if (type == T_INT16)
    {
        i16 *p = val;
        *p = def_val(data, i16);
    }
    else if (type == T_INT32)
    {
        i32 *p = val;
        *p = def_val(data, i32);
    }
    else if (type == T_UINT16)
    {
        u16 *p = val;
        *p = def_val(data, u16);
    }
    else if (type == T_UINT32)
    {
        u32 *p = val;
        *p = def_val(data, u32);
    }
    else if (type == T_UINT8)
    {
        u8 *p = val;
        *p = def_val(data, u8);
    }
}
// void set_element(Element *e, u8 type, u32 data)
// {
//     e->size = type_get_size(type);
//     e->type = type;
//     e->data = data;
// }
